﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MainForm.cs" company="SMART business">
//   Copyright (c) 2014 All Rights Reserved
// </copyright>
// <summary>
//   The main form.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace ComparisonTool.Forms
{
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.IO;
    using System.Windows.Forms;

    using ComparisonTool.Forms.Interfaces;
    using ComparisonTool.Models;

    /// <summary>
    /// The main form.
    /// </summary>
    public partial class MainForm : Form, IMainForm
    {
        private delegate void Delegate1Opt<in T>(T arg);

        private delegate void Delegate2Opt<in T, in T1>(T arg1, T1 arg2);

        /// <summary>
        /// The inverse.
        /// </summary>
        private bool inverse = true;

        /// <summary>
        /// The _form 1.
        /// </summary>
        private ComboboxItem form1;

        /// <summary>
        /// The _form 2.
        /// </summary>
        private ComboboxItem form2;

        /// <summary>
        /// The _sort column.
        /// </summary>
        private int sortColumn = -1;

        /// <summary>
        /// Initializes a new instance of the <see cref="MainForm"/> class.
        /// </summary>
        public MainForm()
        {
            this.InitializeComponent();

            this.lstEntities.ColumnClick += this.ColumnHeaderClick;
            this.lstAttributes1.ColumnClick += this.ColumnHeaderClick;
            this.lstAttributes2.ColumnClick += this.ColumnHeaderClick;
            this.lstEvents1.ColumnClick += this.ColumnHeaderClick;
            this.lstEvents2.ColumnClick += this.ColumnHeaderClick;
            this.lstRules1.ColumnClick += this.ColumnHeaderClick;
            this.lstRules2.ColumnClick += this.ColumnHeaderClick;

            this.firstEntities.ColumnClick += this.ColumnHeaderClick;
            this.secondEntities.ColumnClick += this.ColumnHeaderClick;

            this.lstEntities.SelectedIndexChanged += this.Entity_OnSelect;

            this.cbFormE1.SelectedIndexChanged += this.Form1_OnSelect;
            this.cbFormE2.SelectedIndexChanged += this.Form2_OnSelect;

            this.cbForms1.SelectedIndexChanged += this.Form1_OnSelect;
            this.cbForms2.SelectedIndexChanged += this.Form2_OnSelect;

            this.cbFormR1.SelectedIndexChanged += this.Form1_OnSelect;
            this.cbFormR2.SelectedIndexChanged += this.Form2_OnSelect;

            this.tabs.Selected += this.Tab_OnSelect;

            this.btnLoadEntities.Click += this.LoadEntitiesClick;
            this.btnEventsCompare.Click += this.CompareClick;
            this.btnAttributeCompare.Click += this.CompareClick;
            this.btnTabCompare.Click += this.CompareClick;
            this.btnSectionsCompare.Click += this.CompareClick;
            this.btnRelationshipCompare.Click += this.CompareClick;
            this.btnRulesCompare.Click += this.CompareClick;

            this.cbForms1.SelectedIndexChanged += this.FormsSelectedIndexChanged;
            this.cbFormE2.SelectedIndexChanged += this.FormsSelectedIndexChanged;
            this.cbFormR1.SelectedIndexChanged += this.FormsSelectedIndexChanged;
            this.cbFormR2.SelectedIndexChanged += this.FormsSelectedIndexChanged;
            this.cbForms1.SelectedIndexChanged += this.FormsSelectedIndexChanged;
            this.cbForms2.SelectedIndexChanged += this.FormsSelectedIndexChanged;

            this.btnUploadExcelFile.Click += this.UploadExcelFileClick;

            this.MainViewItem.Click += this.MainViewItemClick;
            this.entitiesCompare.Click += this.EntitiesCompareClick;

            this.showSameEntity.Click += this.ShowSameEntityClick;
            this.showDistinctEntities.Click += this.ShowDistinctEntitiesClick;

            this.inverseCompare.Click += this.InverseComparing;
        }

        /// <summary>
        /// The inverse comparing.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void InverseComparing(object sender, EventArgs e)
        {
            if (this.InverseCompare != null)
            {
                this.InverseCompare(this, e);

                this.inverse = !this.inverse;

                this.inverseCompare.Text = this.inverse ? @"Inverse comparing (Intersect)." : @"Inverse comparing (Except).";
            }
        }

        /// <summary>
        /// The show distinct entities click.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void ShowDistinctEntitiesClick(object sender, EventArgs e)
        {
            if (this.ShowDistinctEntity != null)
            {
                this.ShowDistinctEntity(this, e);
            }
        }

        /// <summary>
        /// The show same entitities click.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void ShowSameEntityClick(object sender, EventArgs e)
        {
            if (this.ShowSameEntities != null)
            {
                this.ShowSameEntities(this, e);
            }
        }

        /// <summary>
        /// The compare lists.
        /// </summary>
        /// <param name="list1">
        /// The list 1.
        /// </param>
        /// <param name="list2">
        /// The list 2.
        /// </param>
        /// <param name="id">
        /// The id.
        /// </param>
        private void CompareLists(ListView.ListViewItemCollection list1, ListView.ListViewItemCollection list2, int id = 1)
        {
            foreach (ListViewItem item1 in list1)
            {
                foreach (ListViewItem item2 in list2)
                {
                    if (item1.SubItems[id].Text == item2.SubItems[id].Text)
                    {
                        if (item1.SubItems[0].Text != item2.SubItems[0].Text)
                        {
                            item1.SubItems[0].BackColor = Color.Bisque;
                            item2.SubItems[0].BackColor = Color.Bisque;

                            item1.UseItemStyleForSubItems = false;
                            item2.UseItemStyleForSubItems = false;
                        }

                        if (item1.SubItems[2].Text != item2.SubItems[2].Text)
                        {
                            item1.SubItems[2].BackColor = Color.LightBlue;
                            item2.SubItems[2].BackColor = Color.LightBlue;

                            item1.UseItemStyleForSubItems = false;
                            item2.UseItemStyleForSubItems = false;
                        }

                        if (item1.SubItems.Count > 3 && item2.SubItems.Count > 3)
                        {
                            if (item1.SubItems[3].Text != item2.SubItems[3].Text)
                            {
                                item1.SubItems[3].BackColor = Color.Coral;
                                item2.SubItems[3].BackColor = Color.Coral;

                                item1.UseItemStyleForSubItems = false;
                                item2.UseItemStyleForSubItems = false;
                            }
                        }

                        if (item1.SubItems.Count > 4)
                        {
                            if (item1.SubItems[4].Text != item2.SubItems[4].Text)
                            {
                                item1.SubItems[4].BackColor = Color.DarkSeaGreen;
                                item2.SubItems[4].BackColor = Color.DarkSeaGreen;

                                item1.UseItemStyleForSubItems = false;
                                item2.UseItemStyleForSubItems = false;
                            }
                        }

                        if (item1.SubItems.Count > 5)
                        {
                            if (item1.SubItems[4].Text != item2.SubItems[4].Text)
                            {
                                item1.SubItems[4].BackColor = Color.PowderBlue;
                                item2.SubItems[4].BackColor = Color.PowderBlue;

                                item1.UseItemStyleForSubItems = false;
                                item2.UseItemStyleForSubItems = false;
                            }
                        }

                        break;
                    }
                }
            }
        }

        /// <summary>
        /// The main view item click.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void MainViewItemClick(object sender, EventArgs e)
        {
            this.mainView.Visible = true;
            this.entitiesCompareView.Visible = false;

            this.ViewVisibleChange();
        }

        /// <summary>
        /// The view visible change.
        /// </summary>
        private void ViewVisibleChange()
        {
            this.btnAttributeCompare.Visible = this.mainView.Visible;
            this.btnSectionsCompare.Visible = this.mainView.Visible;
            this.btnTabCompare.Visible = this.mainView.Visible;
            this.btnRelationshipCompare.Visible = this.mainView.Visible;
            this.btnEventsCompare.Visible = this.mainView.Visible;
            this.btnRulesCompare.Visible = this.mainView.Visible;

            this.showSameEntity.Visible = this.entitiesCompareView.Visible;
            this.showDistinctEntities.Visible = this.entitiesCompareView.Visible;
            this.inverseCompare.Visible = this.mainView.Visible;
        }

        /// <summary>
        /// The set entities list.
        /// </summary>
        /// <param name="id">
        ///     The id.
        /// </param>
        /// <param name="entities">
        ///     The entities.
        /// </param>
        public void SetEntitiesList(int id, List<object> entities)
        {
            var list = new ListView();

            switch (id)
            {
                case 1:
                    list = this.firstEntities;
                    break;

                case 2:
                    list = this.secondEntities;
                    break;
            }

            if (list.InvokeRequired)
            {
                var callback = new Delegate2Opt<int, List<object>>(this.SetEntitiesList);
                this.Invoke(callback, id, entities);
            }
            else
            {
                list.BeginUpdate();

                list.Items.Clear();

                foreach (dynamic entity in entities)
                {
                    var listItem = new ListViewItem(entity.DisplayName);
                    listItem.SubItems.Add(entity.LogicalName);
                    listItem.SubItems.Add(entity.IsAuditEnabled);
                    listItem.SubItems.Add(entity.IsDuplicateDetectionEnabled);

                    list.Items.Add(listItem);
                }

                this.CompareLists(this.firstEntities.Items, this.secondEntities.Items);

                list.EndUpdate();
            }
        }

        #region IMainForm

        /// <summary>
        /// The entities compare.
        /// </summary>
        public event EventHandler EntitiesCompare;

        /// <summary>
        /// The show same entities.
        /// </summary>
        public event EventHandler ShowSameEntities;

        /// <summary>
        /// The show distinct entity.
        /// </summary>
        public event EventHandler ShowDistinctEntity;

        /// <summary>
        /// The load entities.
        /// </summary>
        public event EventHandler LoadEntities;

        /// <summary>
        /// The load double entities.
        /// </summary>
        public event EventHandler LoadDoubleEntities;

        /// <summary>
        /// The compare attributes.
        /// </summary>
        public event EventHandler CompareAttributes;

        /// <summary>
        /// The entity select.
        /// </summary>
        public event EventHandler EntitySelect;

        /// <summary>
        /// The form selected.
        /// </summary>
        public event EventHandler FormSelected;

        /// <summary>
        /// The inverse compare.
        /// </summary>
        public event EventHandler InverseCompare;

        /// <summary>
        /// The export to excel.
        /// </summary>
        public event EventHandler ExportToExcel;

        #endregion

        /// <summary>
        /// Gets or sets the form 1.
        /// </summary>
        private ComboboxItem Form1
        {
            get { return this.form1 ?? new ComboboxItem(); }
            set { this.form1 = value; }
        }

        /// <summary>
        /// Gets or sets the form 2.
        /// </summary>
        private ComboboxItem Form2
        {
            get { return this.form2 ?? new ComboboxItem(); }
            set { this.form2 = value; }
        }

        /// <summary>
        /// The get form 1.
        /// </summary>
        /// <returns>
        /// The <see cref="ComboboxItem"/>.
        /// </returns>
        public ComboboxItem GetForm1()
        {
            return this.Form1;
        }

        /// <summary>
        /// The get form 2.
        /// </summary>
        /// <returns>
        /// The <see cref="ComboboxItem"/>.
        /// </returns>
        public ComboboxItem GetForm2()
        {
            return this.Form2;
        }

        /// <summary>
        /// The set entities list.
        /// </summary>
        /// <param name="entities">
        /// The entities.
        /// </param>
        public void SetEntitiesList(List<object> entities)
        {
            if (this.lstEntities.InvokeRequired)
            {
                var callback = new Delegate1Opt<List<object>>(this.SetEntitiesList);
                this.Invoke(callback, entities);
            }
            else
            {
                this.lstEntities.BeginUpdate();

                this.lstEntities.Items.Clear();

                var items = new List<ListViewItem>();
                foreach (dynamic entity in entities)
                {
                    var listViewItem = new ListViewItem(entity.DisplayName);
                    listViewItem.SubItems.Add(entity.LogicalName);
                    items.Add(listViewItem);
                }

                this.lstEntities.Items.AddRange(items.ToArray());

                this.lstEntities.EndUpdate();
            }
        }

        /// <summary>
        /// The entities compare click.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void EntitiesCompareClick(object sender, EventArgs e)
        {
            if (this.EntitiesCompare != null)
            {
                this.EntitiesCompare(this, e);
            }

            if (this.connection1.Text.StartsWith(@"Connected to") && this.connection2.Text.StartsWith(@"Connected to"))
            {
                this.mainView.Visible = false;
                this.entitiesCompareView.Visible = true;
            }

            this.ViewVisibleChange();
        }

        /// <summary>
        /// The set current entity value.
        /// </summary>
        public void SetCurrentEntityValue()
        {
            this.lblSelectedEntityName.Text = string.Empty;
        }

        /// <summary>
        /// The set forms 1 list.
        /// </summary>
        /// <param name="forms">
        /// The forms.
        /// </param>
        public void SetForms1List(List<object> forms)
        {
            if (forms == null)
            {
                return;
            }

            if (this.cbForms1.InvokeRequired)
            {
                var callback = new Delegate1Opt<List<object>>(this.SetForms1List);
                this.Invoke(callback, forms);
            }
            else
            {
                this.cbForms1.Items.Clear();
                this.cbFormE1.Items.Clear();
                this.cbFormR1.Items.Clear();

                foreach (dynamic form in forms)
                {
                    this.cbForms1.Items.Add(new ComboboxItem { Name = form.Name, Value = form.Value });
                    this.cbFormE1.Items.Add(new ComboboxItem { Name = form.Name, Value = form.Value });
                    this.cbFormR1.Items.Add(new ComboboxItem { Name = form.Name, Value = form.Value });
                }
            }
        }

        /// <summary>
        /// The set forms 2 list.
        /// </summary>
        /// <param name="forms">
        ///     The forms.
        /// </param>
        public void SetForms2List(List<object> forms)
        {
            if (forms == null)
            {
                return;
            }

            if (this.cbForms2.InvokeRequired)
            {
                var callback = new Delegate1Opt<List<object>>(this.SetForms2List);
                this.Invoke(callback, forms);
            }
            else
            {
                this.cbForms2.Items.Clear();
                this.cbFormE2.Items.Clear();
                this.cbFormR2.Items.Clear();

                foreach (dynamic form in forms)
                {
                    this.cbForms2.Items.Add(new ComboboxItem { Name = form.Name, Value = form.Value });
                    this.cbFormE2.Items.Add(new ComboboxItem { Name = form.Name, Value = form.Value });
                    this.cbFormR2.Items.Add(new ComboboxItem { Name = form.Name, Value = form.Value });
                }
            }
        }

        public void SetAttributesList(int id, List<object> attributes)
        {
            ListView attributesList;

            switch (id)
            {
                case 1:
                    attributesList = this.lstAttributes1;
                    break;
                case 2:
                    attributesList = this.lstAttributes2;
                    break;
                default:
                    throw new InvalidDataException("Incorrect organisation Id.");
            }

            if (attributesList.InvokeRequired)
            {
                var callback = new Delegate2Opt<int, List<object>>(this.SetAttributesList);
                this.Invoke(callback, id, attributes);
            }
            else
            {
                attributesList.BeginUpdate();

                foreach (dynamic attribute in attributes)
                {
                    var item = new ListViewItem(attribute.DisplayName);
                    item.SubItems.Add(attribute.Name);
                    item.SubItems.Add(attribute.TypeName);
                    item.SubItems.Add(attribute.IsReadOnly);
                    item.SubItems.Add(attribute.IsHidden);

                    attributesList.Items.Add(item);
                }

                this.CompareLists(this.lstAttributes1.Items, this.lstAttributes2.Items);

                attributesList.EndUpdate();
            }
        }

        /// <summary>
        /// The set entities count.
        /// </summary>
        /// <param name="count">
        /// The count.
        /// </param>
        public void SetEntitiesCount(string count)
        {
            this.lblEntitiesCount.Text = count;
        }

        /// <summary>
        /// The set event 1 list.
        /// </summary>
        /// <param name="id">
        /// </param>
        /// <param name="events">
        /// The events.
        /// </param>
        public void SetEventsList(int id, List<object> events)
        {
            ListView lstEvents;

            switch (id)
            {
                case 1:
                    lstEvents = this.lstEvents1;
                    break;
                case 2:
                    lstEvents = this.lstEvents2;
                    break;
                default:
                    throw new InvalidDataException("Incorrect organisation Id.");
            }

            if (lstEvents.InvokeRequired)
            {
                var callback = new Delegate2Opt<int, List<object>>(this.SetEventsList);
                this.Invoke(callback, id, events);
            }
            else
            {
                foreach (dynamic item in events)
                {
                    var listViewItem = new ListViewItem(item.Name);
                    listViewItem.SubItems.Add(item.AttributeDisplayName);
                    listViewItem.SubItems.Add(item.Attribute);
                    listViewItem.SubItems.Add(item.LibraryName);
                    listViewItem.SubItems.Add(item.FunctionName);

                    lstEvents.Items.Add(listViewItem);
                }

                this.CompareLists(this.lstEvents1.Items, this.lstEvents2.Items, 4);
            }
        }

        /// <summary>
        /// The set rules 2 list.
        /// </summary>
        /// <param name="id"></param>
        /// <param name="rules">
        ///     The rules.
        /// </param>
        public void SetRulesList(int id, List<object> rules)
        {
            ListView lstRules;

            switch (id)
            {
                case 1:
                    lstRules = this.lstRules1;
                    break;
                case 2:
                    lstRules = this.lstRules2;
                    break;
                default:
                    throw new InvalidDataException("Incorrect organisation Id.");
            }

            if (lstRules.InvokeRequired)
            {
                var callback = new Delegate2Opt<int, List<object>>(this.SetRulesList);
                this.Invoke(callback, id, rules);
            }
            else
            {
                foreach (dynamic item in rules)
                {
                    var listViewItem = new ListViewItem(item.CreatedBy);
                    listViewItem.SubItems.Add(item.RuleName);
                    listViewItem.SubItems.Add(item.State);
                    listViewItem.SubItems.Add(item.IsManaged);

                    lstRules.Items.Add(listViewItem);
                }

                this.CompareLists(this.lstRules1.Items, this.lstRules2.Items);
            }
        }

        /// <summary>
        /// The get main form.
        /// </summary>
        /// <returns>
        /// The <see cref="Control"/>.
        /// </returns>
        public Control GetMainForm()
        {
            return this;
        }
        
        /// <summary>
        /// The set status connection 1.
        /// </summary>
        /// <param name="statusMessage">
        /// The status message.
        /// </param>
        /// <param name="id">
        /// Connection control identifier.
        /// </param>
        public void SetStatusConnection(string statusMessage, int id)
        {
            switch (id)
            {
                case 1:
                    this.connection1.Text = statusMessage;
                    break;

                case 2:
                    this.connection2.Text = statusMessage;
                    break;
            }
        }

        /// <summary>
        /// The set entity caption.
        /// </summary>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <param name="caption">
        /// The caption.
        /// </param>
        public void SetEntityCaption(int id, string caption)
        {
            GroupBox groupBox = null;
            switch (id)
            {
                case 1:
                    groupBox = this.firstEntitiesGroupBox;
                    break;

                case 2:
                    groupBox = this.secondEntitiesGroupBox;
                    break;
            }

            if (groupBox != null)
            {
                if (groupBox.InvokeRequired)
                {
                    var callback = new Delegate2Opt<int, string>(this.SetEntityCaption);
                    this.Invoke(callback, id, caption);
                }
                else
                {
                    groupBox.Text = caption;
                }
            }
        }

        public int GetSelectedEntityCount()
        {
            return this.lstEntities.SelectedItems.Count;
        }

        /// <summary>
        /// The get connect control 1.
        /// </summary>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <returns>
        /// The <see cref="ToolStripDropDownButton"/>.
        /// </returns>
        public ToolStripDropDownButton GetConnectControl(int id)
        {
            switch (id)
            {
                case 1:
                    return this.connection1;
                case 2:
                    return this.connection2;
            }

            return this.connection1;
        }

        /// <summary>
        /// The set org 1 caption.
        /// </summary>
        /// <param name="text">
        /// The count.
        /// </param>
        public void SetOrg1Caption(string text)
        {
            if (this.pnlOrg1.InvokeRequired)
            {
                var callback = new Delegate1Opt<string>(this.SetOrg1Caption);
                this.Invoke(callback, text);
            }
            else
            {
                this.pnlOrg1.Text = text;
                this.pnlOrgE1.Text = text;
                this.pnlOrgR1.Text = text;
            }
        }

        /// <summary>
        /// The set org 2 caption.
        /// </summary>
        /// <param name="text">
        /// The count.
        /// </param>
        public void SetOrg2Caption(string text)
        {
            if (this.pnlOrg2.InvokeRequired)
            {
                var callback = new Delegate1Opt<string>(this.SetOrg2Caption);
                this.Invoke(callback, text);
            }
            else
            {
                this.pnlOrg2.Text = text;
                this.pnlOrgE2.Text = text;
                this.pnlOrgR2.Text = text;
            }
        }

        /// <summary>
        /// The column header click.
        /// </summary>
        /// <param name="obj">
        /// The link to header.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void ColumnHeaderClick(object obj, ColumnClickEventArgs e)
        {
            var list = obj as ListView;

            if (list == null)
            {
                return;
            }

            if (e.Column != this.sortColumn)
            {
                this.sortColumn = e.Column;
                list.Sorting = SortOrder.Ascending;
            }
            else
            {
                list.Sorting = list.Sorting == SortOrder.Ascending ? SortOrder.Descending : SortOrder.Ascending;
            }

            list.Sort();

            list.ListViewItemSorter = new ListItem(e.Column, list.Sorting);
        }

        /// <summary>
        /// The tab_ on select.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void Tab_OnSelect(object sender, TabControlEventArgs e)
        {
            var control = sender as TabControl;
            if (control == null)
            {
                return;
            }

            var tabName = control.SelectedTab.Name;

            switch (tabName)
            {
                case "attributeTab":
                    this.btnAttributeCompare.Enabled = true;
                    this.btnTabCompare.Enabled = true;
                    this.btnSectionsCompare.Enabled = true;
                    this.btnRelationshipCompare.Enabled = true;

                    this.btnEventsCompare.Enabled = false;

                    this.btnRulesCompare.Enabled = false;

                    this.cbForms1.Text = this.Form1.Name;
                    this.cbForms2.Text = this.Form2.Name;
                    break;
                case "eventsTab":
                    this.btnAttributeCompare.Enabled = false;
                    this.btnTabCompare.Enabled = false;
                    this.btnSectionsCompare.Enabled = false;
                    this.btnRelationshipCompare.Enabled = false;

                    this.btnEventsCompare.Enabled = true;

                    this.btnRulesCompare.Enabled = false;

                    this.cbFormE1.Text = this.Form1.Name;
                    this.cbFormE2.Text = this.Form2.Name;
                    break;

                case "rulesTab":
                    
                    this.btnAttributeCompare.Enabled = false;
                    this.btnTabCompare.Enabled = false;
                    this.btnSectionsCompare.Enabled = false;
                    this.btnRelationshipCompare.Enabled = false;

                    this.btnEventsCompare.Enabled = false;

                    this.btnRulesCompare.Enabled = true;

                    this.cbFormR1.Text = this.Form1.Name;
                    this.cbFormR2.Text = this.Form2.Name;
                    break;
            }
        }

        /// <summary>
        /// The entity_ on select.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void Entity_OnSelect(object sender, EventArgs e)
        {
            var entitiesList = sender as ListView;
            if (entitiesList == null || !entitiesList.SelectedItems.Count.Equals(1))
            {
                return;
            }

            this.ClearForms();

            this.lblSelectedEntityName.Text = @"Current entity: " + entitiesList.SelectedItems[0].Text;

            if (this.EntitySelect != null)
            {
                this.EntitySelect(entitiesList.SelectedItems[0].SubItems[1].Text, e);
            }
        }

        /// <summary>
        /// The form 1_ on select.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void Form1_OnSelect(object sender, EventArgs e)
        {
            this.Form1 = (ComboboxItem)((ComboBox)sender).SelectedItem;
        }

        /// <summary>
        /// The form 2_ on select.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void Form2_OnSelect(object sender, EventArgs e)
        {
            this.Form2 = (ComboboxItem)((ComboBox)sender).SelectedItem;
        }

        /// <summary>
        /// The clear forms.
        /// </summary>
        private void ClearForms()
        {
            this.cbForms1.Items.Clear();
            this.cbForms2.Items.Clear();

            this.lstAttributes1.Items.Clear();
            this.lstAttributes2.Items.Clear();

            this.lstEvents1.Items.Clear();
            this.lstEvents2.Items.Clear();

            this.lstRules1.Items.Clear();
            this.lstRules2.Items.Clear();

            this.cbFormE1.Items.Clear();
            this.cbFormE2.Items.Clear();

            this.cbFormR1.Items.Clear();
            this.cbFormR2.Items.Clear();

            this.cbForms1.Text = string.Empty;
            this.cbForms2.Text = string.Empty;

            this.cbFormE1.Text = string.Empty;
            this.cbFormE2.Text = string.Empty;

            this.cbFormR1.Text = string.Empty;
            this.cbFormR2.Text = string.Empty;

            this.Form1 = null;
            this.Form2 = null;
        }

        /// <summary>
        /// The exit_ click.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void ExitClick(object sender, EventArgs e)
        {
            Application.Exit();
        }

        /// <summary>
        /// The upload excel file click.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void UploadExcelFileClick(object sender, EventArgs e)
        {
            if (this.ExportToExcel != null)
            {
                this.ExportToExcel(this, e);
            }
        }

        /// <summary>
        /// The load entities click.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void LoadEntitiesClick(object sender, EventArgs e)
        {
            this.ClearForms();

            if (this.LoadEntities != null && this.mainView.Visible)
            {
                this.lblEntitiesCount.Text = string.Empty;
                this.LoadEntities(this, EventArgs.Empty);
            }
            else if (this.LoadDoubleEntities != null)
            {
                this.LoadDoubleEntities(this, EventArgs.Empty);
            }
        }

        /// <summary>
        /// The compare_ click.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void CompareClick(object sender, EventArgs e)
        {
            if (this.CompareAttributes == null)
            {
                return;
            }

            this.lstAttributes1.Items.Clear();
            this.lstAttributes2.Items.Clear();

            this.lstEvents1.Items.Clear();
            this.lstEvents2.Items.Clear();

            this.lstRules1.Items.Clear();
            this.lstRules2.Items.Clear();

            var item = sender as ToolStripItem;

            if (item != null)
            {
                var compareType = CompareType.Attributes;

                switch (item.Name)
                {
                    case "btnAttributeCompare":
                        compareType = CompareType.Attributes;
                        break;
                    case "btnSectionsCompare":
                        compareType = CompareType.Sections;
                        break;
                    case "btnTabCompare":
                        compareType = CompareType.Tabs;
                        break;
                    case "btnRelationshipCompare":
                        compareType = CompareType.Relationships;
                        break;
                    case "btnEventsCompare":
                        compareType = CompareType.Events;
                        break;
                    case "btnRulesCompare":
                        compareType = CompareType.BusinessRules;
                        break;
                }

                this.CompareAttributes(compareType, EventArgs.Empty);
            }
        }

        /// <summary>
        /// The forms_ selected index changed.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void FormsSelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.FormSelected != null)
            {
                this.FormSelected(sender, EventArgs.Empty);
            }
        }

        private void lstRules2_SelectedIndexChanged(object sender, EventArgs e)
        {

        }
    }
}
